home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / programm / gemfsc20 / gemfsc20.lzh / GEMFUNCS / OBJNSLID.C < prev    next >
C/C++ Source or Header  |  1993-03-20  |  11KB  |  398 lines

  1. /**************************************************************************
  2.  *
  3.  *************************************************************************/
  4.  
  5. #include "gemfintl.h"
  6.  
  7. /*-------------------------------------------------------------------------
  8.  *
  9.  *-----------------------------------------------------------------------*/
  10.  
  11. static OBJECT nslider_objects[]  = {
  12.  { -1,    1,    4, G_IBOX,       NONE,       NORMAL,     (_Ob_spec_t)0x00001181L,      0x0000, 0x0000, 0x0000, 0x0000},
  13.  {    2, -1, -1, G_BOXCHAR,  NONE,       NORMAL,     (_Ob_spec_t)0x04FF1181L,      0x0000, 0x0000, 0x0000, 0x0000},
  14.  {    4,    3,    3, G_BOX,       NONE,       NORMAL,     (_Ob_spec_t)0x00FF1191L,      0x0000, 0x0000, 0x0000, 0x0000},
  15.  {    2, -1, -1, G_BUTTON,   NONE,       NORMAL,     (_Ob_spec_t)NULL,              0x0000, 0x0000, 0x0000, 0x0000},
  16.  {    0, -1, -1, G_BOXCHAR,  LASTOB,       NORMAL,     (_Ob_spec_t)0x03FF1181L,      0x0000, 0x0000, 0x0000, 0x0000},
  17. };
  18.  
  19. #define NSLIDE_ROOT         0
  20. #define NSLIDE_DOWNARROW    1
  21. #define NSLIDE_PAGE         2
  22. #define NSLIDE_SLIDER        3
  23. #define NSLIDE_UPARROW        4
  24.  
  25. #define NSLIDE_ARROW_WIDTH        (gl_wbox)
  26. #define MIN_NSLIDE_OBJECT_WIDTH (4*NSLIDE_ARROW_WIDTH)
  27.  
  28. /*-------------------------------------------------------------------------
  29.  *
  30.  *-----------------------------------------------------------------------*/
  31.  
  32. typedef struct nslide_info {
  33.     XUSERBLK xub;                    /* standard XUSERDEF header                              */
  34.     short     statusobj;             /* obj in main tree that shows cur selection          */
  35.     long     min;                    /* minimum numeric value slider can have                    */
  36.     long     max;                    /* maximum numeric value slider can have                    */
  37.     short     wpage;                 /* width of pager bar in pixels                          */
  38.     short     wslider;                /* width of slider box in pixels                        */
  39.     OBJECT     dialog[5];             /* rectangles describing slider                      */
  40. } NSLIDEINFO;
  41.  
  42. /*-------------------------------------------------------------------------
  43.  *
  44.  *-----------------------------------------------------------------------*/
  45.  
  46. #ifdef GEMFAST_PROTOS
  47.  
  48.   typedef void GCALLBACK (EVNREPEATFUNC)(void *udata, short mx, short my);
  49.  
  50.   INTERNAL_VFUNC        clip_slider_value(NSLIDEINFO *pinfo);
  51.   INTERNAL_VFUNC        render_nslide(NSLIDEINFO *pinfo, short startobj, GRECT *cliprect);
  52.   static long GCALLBACK see_nslide(XPARMBLK *pb);
  53.   static void GCALLBACK inc_slider(void *udata, short mx, short my);
  54.   static void GCALLBACK dec_slider(void *udata, short mx, short my);
  55.   static void            repeat_on_button_down(EVNREPEATFUNC *pfunc, void *udata);
  56.   static void GCALLBACK udslider(OBJECT *ptree, short obj, short slidepos, void *udata);
  57.   static XUBT_STATUS GCALLBACK feel_nslide(XUSERBLK *xub, short mx, short my, short clicks);
  58.  
  59. #else
  60.  
  61.   typedef void GCALLBACK (EVNREPEATFUNC)();
  62.  
  63. #endif
  64.  
  65. INTERNAL_VFUNC clip_slider_value(pinfo)
  66.     NSLIDEINFO *pinfo;
  67. /*****************************************************************************
  68.  *
  69.  ****************************************************************************/
  70. {
  71.     long    value = (long)pinfo->xub.ob_spec;
  72.  
  73.     if (value < pinfo->min) {
  74.         value = pinfo->min;
  75.     } else if (value > pinfo->max) {
  76.         value = pinfo->max;
  77.     }
  78.  
  79.     pinfo->xub.ob_spec = (_Ob_spec_t)value;
  80. }
  81.  
  82. INTERNAL_VFUNC render_nslide(pinfo, startobj, cliprect)
  83.     NSLIDEINFO    *pinfo;
  84.     short        startobj;
  85.     GRECT        *cliprect;
  86. /*****************************************************************************
  87.  *
  88.  ****************************************************************************/
  89. {
  90.     long    value;
  91.     long    vrange;
  92.     short    prange;
  93.     short    nchars;
  94.     char    buf[20];
  95.     OBJECT    *dialog = pinfo->dialog;
  96.  
  97.     clip_slider_value(pinfo);
  98.  
  99.     nchars = sprintf(buf, "%ld", pinfo->xub.ob_spec);
  100.     dialog[NSLIDE_SLIDER].ob_width = (nchars+1) * gl_wchar;
  101.     dialog[NSLIDE_SLIDER].ob_spec  = (_Ob_spec_t)buf;
  102.  
  103.     value = (long)pinfo->xub.ob_spec - pinfo->min;
  104.     vrange = pinfo->max - pinfo->min;
  105.     prange = dialog[NSLIDE_PAGE].ob_width - dialog[NSLIDE_SLIDER].ob_width;
  106.  
  107.     dialog[NSLIDE_SLIDER].ob_x =
  108.         (short)((((value*1000L)/vrange)*(prange))/1000L);
  109.  
  110.     obj__draw(dialog, startobj, MAX_DEPTH, cliprect);
  111. }
  112.  
  113. static long GCALLBACK see_nslide(pb)
  114.     XPARMBLK *pb;
  115. /*****************************************************************************
  116.  *
  117.  ****************************************************************************/
  118. {
  119.     NSLIDEINFO *pinfo = (NSLIDEINFO *)pb->pub;
  120.  
  121.     pinfo->dialog[ROOT].ob_x = pb->drawrect.g_x;
  122.     pinfo->dialog[ROOT].ob_y = pb->drawrect.g_y;
  123.  
  124.     render_nslide(pinfo, ROOT, &pb->cliprect);
  125.  
  126.     return 0;
  127. }
  128.  
  129. static void GCALLBACK inc_slider(udata, mx, my)
  130.     void    *udata;
  131.     short    mx;
  132.     short    my;
  133. /*****************************************************************************
  134.  *
  135.  ****************************************************************************/
  136. {
  137.     NSLIDEINFO *pinfo = udata;
  138.  
  139.     pinfo->xub.ob_spec = (_Ob_spec_t)((long)pinfo->xub.ob_spec + 1);
  140.     render_nslide(pinfo, NSLIDE_PAGE, &gl_rwdesk);
  141. }
  142.  
  143. static void GCALLBACK dec_slider(udata, mx, my)
  144.     void    *udata;
  145.     short    mx;
  146.     short    my;
  147. /*****************************************************************************
  148.  *
  149.  ****************************************************************************/
  150. {
  151.     NSLIDEINFO *pinfo = udata;
  152.  
  153.     pinfo->xub.ob_spec = (_Ob_spec_t)((long)pinfo->xub.ob_spec - 1);
  154.     render_nslide(pinfo, NSLIDE_PAGE, &gl_rwdesk);
  155. }
  156.  
  157. static void repeat_on_button_down(pfunc, udata)
  158.     EVNREPEATFUNC    *pfunc;
  159.     void            *udata;
  160. /*****************************************************************************
  161.  *
  162.  ****************************************************************************/
  163. {
  164.     short mx, my, mb, dmy;
  165.     short first_time = TRUE;
  166.  
  167.     do    {
  168.         graf_mkstate(&mx, &my, &mb, &dmy);
  169.         if (mb || first_time) {
  170.             (*pfunc)(udata, mx, my);
  171.         }
  172.         first_time = 0;
  173.         evnx_timer(50L);
  174.     } while (mb);
  175. }
  176.  
  177. static void GCALLBACK udslider(ptree, obj, slidepos, udata)
  178.     OBJECT    *ptree;
  179.     short    obj;
  180.     short    slidepos;
  181.     void    *udata;
  182. /*****************************************************************************
  183.  *
  184.  ****************************************************************************/
  185. {
  186.     NSLIDEINFO *pinfo = udata;
  187.     long        value;
  188.     long        vrange;
  189.  
  190.     if (slidepos > 2000) {
  191.         slidepos -= 2000;
  192.     } else if (slidepos > 1000) {
  193.         slidepos -= 1000;
  194.     }
  195.  
  196.     vrange = pinfo->max - pinfo->min;
  197.  
  198.     value = (vrange * (slidepos-1)) / 1000L;
  199.     pinfo->xub.ob_spec = (_Ob_spec_t)(value + pinfo->min);
  200.  
  201.     render_nslide(pinfo, NSLIDE_PAGE, &gl_rwdesk);
  202. }
  203.  
  204. static XUBT_STATUS GCALLBACK feel_nslide(xub, mx, my, clicks)
  205.     XUSERBLK *xub;
  206.     short     mx;
  207.     short     my;
  208.     short     clicks;
  209. /*****************************************************************************
  210.  * routine to handle a click on a slider object.
  211.  ****************************************************************************/
  212. {
  213.     NSLIDEINFO *pinfo = (NSLIDEINFO *)xub;
  214.     short        clickobj;
  215.     XUBT_STATUS rv = XUBT_VALUE;
  216.  
  217.     clickobj = objc_find(pinfo->dialog, ROOT, MAX_DEPTH, mx, my);
  218.     switch (clickobj) {
  219.         case NSLIDE_PAGE:
  220.         case NSLIDE_SLIDER:
  221.             grf_udslidebox(pinfo->dialog, NSLIDE_SLIDER, FALSE, udslider, pinfo);
  222.             break;
  223.         case NSLIDE_DOWNARROW:
  224.             repeat_on_button_down(dec_slider, pinfo);
  225.             break;
  226.         case NSLIDE_UPARROW:
  227.             repeat_on_button_down(inc_slider, pinfo);
  228.             break;
  229.         default:
  230.             rv = XUBT_NONE;
  231.             break;
  232.     }
  233.  
  234.     return rv;
  235. }
  236.  
  237. short obj_make_nslide(ptree, obj, statusobj, min, max)
  238.     OBJECT *ptree;
  239.     short    obj;
  240.     short    statusobj;
  241.     long    min;
  242.     long    max;
  243. /*****************************************************************************
  244.  *
  245.  ****************************************************************************/
  246. {
  247.     register OBJECT      *pobj = &ptree[obj];
  248.     register NSLIDEINFO *pinfo;
  249.  
  250.     /*------------------------------------------------------------------------
  251.      * validate parms.
  252.      *----------------------------------------------------------------------*/
  253.  
  254.     if (0 == apl_vshared()) {
  255.         return gfErr_vdi_handle;
  256.     }
  257.  
  258.     if (pobj->ob_width < MIN_NSLIDE_OBJECT_WIDTH) {
  259.         return gfErr_object_too_small;
  260.     }
  261.  
  262.     if (max <= min) {
  263.         return gfErr_parameter_range;
  264.     }
  265.  
  266.     /*------------------------------------------------------------------------
  267.      * If the object has already been made into a G_NSLIDE extended object,
  268.      * just get its pointer, else make it into such an object.
  269.      *----------------------------------------------------------------------*/
  270.  
  271.     if ((pobj->ob_type & 0x00FF) == G_USERDEF) {
  272.         pinfo = (NSLIDEINFO *)pobj->_Ob_spec;
  273.         if (pinfo->xub.ob_type != G_NSLIDE) {
  274.             return gfErr_wrong_type;
  275.         }
  276.     } else {
  277.         if (NULL == (pinfo = apl_malloc((long)sizeof(*pinfo)))) {
  278.             return gfErr_no_memory;
  279.         }
  280.         obj_mxuserdef(ptree, obj, &pinfo->xub, see_nslide, feel_nslide, (long)sizeof(*pinfo));
  281.         pinfo->xub.ob_type = G_NSLIDE;
  282.         pinfo->xub.ob_spec = 0;
  283.     }
  284.  
  285.     pinfo->min        = min;
  286.     pinfo->max        = max;
  287.     pinfo->wpage    = pobj->ob_width - (2 * NSLIDE_ARROW_WIDTH);
  288.     pinfo->wslider    = NSLIDE_ARROW_WIDTH;
  289.  
  290.     pinfo->statusobj = statusobj;
  291.     if (statusobj != NO_OBJECT) {
  292.         rsc_sstrings(ptree, statusobj, "", -1);
  293.     }
  294.  
  295.     /*------------------------------------------------------------------------
  296.      * build the rectangles describing the on-screen nslide.
  297.      *----------------------------------------------------------------------*/
  298.  
  299.     memcpy(pinfo->dialog, nslider_objects, sizeof(nslider_objects));
  300.  
  301. #define SetRect(idx, x, y, w, h)\
  302.     pinfo->dialog[(idx)].ob_x = (x);\
  303.     pinfo->dialog[(idx)].ob_y = (y);\
  304.     pinfo->dialog[(idx)].ob_width = (w);\
  305.     pinfo->dialog[(idx)].ob_height = (h)
  306.  
  307.     SetRect(ROOT,
  308.         pobj->ob_x,
  309.         pobj->ob_y,
  310.         pobj->ob_width,
  311.         pobj->ob_height);
  312.  
  313.     SetRect(NSLIDE_DOWNARROW,
  314.         0,
  315.         0,
  316.         NSLIDE_ARROW_WIDTH,
  317.         pobj->ob_height);
  318.  
  319.     SetRect(NSLIDE_PAGE,
  320.         NSLIDE_ARROW_WIDTH,
  321.         0,
  322.         pinfo->wpage - 1,
  323.         pobj->ob_height);
  324.  
  325.     SetRect(NSLIDE_SLIDER,
  326.         0,
  327.         0,
  328.         pinfo->wslider,
  329.         pobj->ob_height);
  330.  
  331.     SetRect(NSLIDE_UPARROW,
  332.         NSLIDE_ARROW_WIDTH + pinfo->wpage,
  333.         0,
  334.         NSLIDE_ARROW_WIDTH,
  335.         pobj->ob_height);
  336.  
  337. #undef SetRect
  338.  
  339.     return 0;
  340. }
  341.  
  342. long obj_get_nslide(ptree, obj)
  343.     OBJECT *ptree;
  344.     short    obj;
  345. /*****************************************************************************
  346.  *
  347.  ****************************************************************************/
  348. {
  349.     return obj_gvalue(ptree, obj);
  350. }
  351.  
  352. void obj_set_nslide(ptree, obj, newvalue)
  353.     OBJECT *ptree;
  354.     short    obj;
  355.     long    newvalue;
  356. /*****************************************************************************
  357.  *
  358.  ****************************************************************************/
  359. {
  360.     NSLIDEINFO *pinfo;
  361.  
  362.     if (ptree[obj].ob_flags & INDIRECT) {
  363.         pinfo = *(NSLIDEINFO **)ptree[obj].ob_spec;
  364.     } else {
  365.         pinfo = (NSLIDEINFO *)ptree[obj].ob_spec;
  366.     }
  367.  
  368.     pinfo->xub.ob_spec = (_Ob_spec_t)newvalue;
  369.  
  370.     clip_slider_value(pinfo);
  371. }
  372.  
  373. void obj_change_nslide(ptree, obj, newmin, newmax)
  374.     OBJECT *ptree;
  375.     short    obj;
  376.     long    newmin;
  377.     long    newmax;
  378. /*****************************************************************************
  379.  *
  380.  ****************************************************************************/
  381. {
  382.     NSLIDEINFO *pinfo;
  383.  
  384.     if (ptree[obj].ob_flags & INDIRECT) {
  385.         pinfo = *(NSLIDEINFO **)ptree[obj].ob_spec;
  386.     } else {
  387.         pinfo = (NSLIDEINFO *)ptree[obj].ob_spec;
  388.     }
  389.  
  390.     pinfo->min = newmin;
  391.     pinfo->max = newmax;
  392.  
  393.     clip_slider_value(pinfo);
  394. }
  395.  
  396.  
  397.  
  398.